package com.joysuch.wwyt.licence.controller;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.joysuch.wwyt.bp.entity.BpEnterpriseInfo;
import com.joysuch.wwyt.bp.service.BpEnterpriseInfoService;
import com.joysuch.wwyt.common.entity.BaseEnterpriseEntity;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.DeleteFlag;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BaseModuleMenuMappingService;
import com.joysuch.wwyt.licence.bean.LicenceAnalysisDto;
import com.joysuch.wwyt.licence.bean.LicenceFileDto;
import com.joysuch.wwyt.licence.bean.LicenceFilePermissionDto;
import com.joysuch.wwyt.licence.bean.LicenceModuleAuthPageDto;
import com.joysuch.wwyt.licence.bean.LicencePageDto;
import com.joysuch.wwyt.licence.constant.LicenceStateEnum;
import com.joysuch.wwyt.licence.entity.Licence;
import com.joysuch.wwyt.licence.entity.LicenceModuleAuth;
import com.joysuch.wwyt.licence.exception.LicenceException;
import com.joysuch.wwyt.licence.service.LicenceModuleAuthService;
import com.joysuch.wwyt.licence.service.LicenceService;
import com.joysuch.wwyt.licence.util.FileUtils;
import com.joysuch.wwyt.licence.util.LicUtil;
import com.joysuch.wwyt.util.AESUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * <p>
 * licence表 前端控制器
 * </p>
 *
 * @author jialei
 * @since 2022-04-26
 */
@RestController
@RequestMapping("/base/licences")
public class LicenceController {

    private final LicenceService licenceService;

    private final BaseModuleMenuMappingService baseModuleMenuMappingService;

    private final BaseConfigService baseConfigService;

    private final BpEnterpriseInfoService bpEnterpriseInfoService;

    private final LicenceModuleAuthService licenceModuleAuthService;

    public LicenceController(LicenceService licenceService,
                             BaseModuleMenuMappingService baseModuleMenuMappingService,
                             BaseConfigService baseConfigService,
                             BpEnterpriseInfoService bpEnterpriseInfoService,
                             LicenceModuleAuthService licenceModuleAuthService) {
        this.licenceService = licenceService;
        this.baseModuleMenuMappingService = baseModuleMenuMappingService;
        this.baseConfigService = baseConfigService;
        this.bpEnterpriseInfoService = bpEnterpriseInfoService;
        this.licenceModuleAuthService = licenceModuleAuthService;
    }

    @GetMapping
    public ResultBean listPage(Integer page, Integer size) {
        if (page == null) {
            page = 0;
        }
        page = page + 1;
        if (size == null) {
            size = 20;
        }
        IPage<LicencePageDto> listPage = licenceService.listPage(page, size);
        return ResultBean.pageData(listPage.getRecords(), listPage.getTotal());
    }

    @GetMapping("/modules")
    public ResultBean listModulePage(Integer page, Integer size) {
        if (page == null) {
            page = 0;
        }
        page = page + 1;
        if (size == null) {
            size = 20;
        }
        IPage<LicenceModuleAuthPageDto> listPage = licenceService.listModuleAuthPage(page, size);
        return ResultBean.pageData(listPage.getRecords(), listPage.getTotal());
    }

    /**
     * 上传解析 licence 文件
     *
     * @param file
     * @param companyCode
     * @return
     */
    @PostMapping("/upload")
    public ResultBean upload(MultipartFile file, String companyCode) {
        if (StrUtil.isBlank(companyCode)) {
            throw new LicenceException(102, "企业编码不能为空");
        }
        String allowedApplicationType = "信息化平台";
        int maxFileSize = 5 * 1024 * 1024;
        FileUtils.assertAllowed(file, new String[]{""}, maxFileSize);

        // 解析 licence 内容
        String licence = null;
        try {
            licence = IoUtil.read(file.getInputStream(), StandardCharsets.UTF_8);
            licence = StrUtil.trim(licence);
        } catch (IOException e) {
            e.printStackTrace();
        }
        LicenceFileDto licenceFileDto = null;
        try {
            licenceFileDto = JSON.parseObject(LicUtil.decrypt(licence), LicenceFileDto.class);
        } catch (Exception e) {
            // 不是平台发布的 licence
        }
        if (licenceFileDto == null) {
            try {
                String localLicenceDecrypt = AESUtil.decrypt(licence, BaseConfigCodes.LICENCE_AES_KEY);
                licenceFileDto = JSON.parseObject(localLicenceDecrypt, LicenceFileDto.class);
                licenceFileDto.setLocalLicence(true);
                licence = MD5.create().digestHex(localLicenceDecrypt, StandardCharsets.UTF_8);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (licenceFileDto == null) {
            return ResultBean.fail(LicenceStateEnum.LICENCE_ERROR.getValue(), LicenceStateEnum.LICENCE_ERROR.getDesc());
        }
        // 判断是否为信息化 licence
        String applicationType = licenceFileDto.getApplicationType();
        if (!allowedApplicationType.equals(applicationType)) {
            return ResultBean.fail(LicenceStateEnum.LICENCE_ERROR_TYPE.getValue(), LicenceStateEnum.LICENCE_ERROR_TYPE.getDesc());
        }
        List<LicenceFilePermissionDto> licenceFilePermissionDtoList = null;
        String permissionJson = licenceFileDto.getPermissionJson();
        try {
            licenceFilePermissionDtoList = JSON.parseArray(permissionJson, LicenceFilePermissionDto.class);
        } catch (Exception e) {
            return ResultBean.fail(LicenceStateEnum.LICENCE_PERMISSION_EMPTY.getValue(), LicenceStateEnum.LICENCE_PERMISSION_EMPTY.getDesc());
        }

        // 判断build id
        String licenceBuildId = licenceFileDto.getBuildId();
        if (StrUtil.isBlank(licenceBuildId)) {
            return ResultBean.fail(LicenceStateEnum.LICENCE_ERROR_TYPE.getValue(), LicenceStateEnum.LICENCE_ERROR_TYPE.getDesc());
        }
        BpEnterpriseInfo enterpriseInfo = bpEnterpriseInfoService.findByOrgCode(companyCode);
        if (enterpriseInfo == null) {
            return ResultBean.fail(102, "企业编码不匹配");
        }
        // 查找是否解析过相同licence
        Licence oldLicence = licenceService.getByLicenceCode(enterpriseInfo.getTenentId(), companyCode, licence);
        if (oldLicence != null) {
            return ResultBean.fail(LicenceStateEnum.FILE_EXIST.getValue(), LicenceStateEnum.FILE_EXIST.getDesc());
        }
        if (!licenceFileDto.isLocalLicence()) {
            BaseConfig buildIdConfig = baseConfigService.findConfig(enterpriseInfo.getTenentId(), companyCode, BaseConfigCodes.LOCATE_CURRENT_BUILD_ID);
            if (buildIdConfig == null ) {
                return ResultBean.fail(LicenceStateEnum.LICENCE_NOT_FOUND_BUILD_ID.getValue(), LicenceStateEnum.LICENCE_NOT_FOUND_BUILD_ID.getDesc());
            }
            String buildId = buildIdConfig.getValue();
            if (StrUtil.isBlank(buildId)) {
                baseConfigService.updateConfigValue(buildIdConfig, licenceBuildId);
            } else if (!licenceBuildId.equals(buildId)) {
                return ResultBean.fail(LicenceStateEnum.LICENCE_ERROR_BUILD_ID.getValue(), LicenceStateEnum.LICENCE_ERROR_BUILD_ID.getDesc());
            }
        }

        long startDateTimestamp = licenceFileDto.getStartDate();
        long endDateTimestamp = licenceFileDto.getEndDate();


        // 更新企业名称，更新模块授权表信息
        LicenceAnalysisDto licenceAnalysisDto = new LicenceAnalysisDto();
        licenceAnalysisDto.setTenentId(enterpriseInfo.getTenentId());
        licenceAnalysisDto.setOrgCode(companyCode);
        licenceAnalysisDto.setCompanyName(licenceFileDto.getBuildName());
        licenceAnalysisDto.setStartDate(startDateTimestamp);
        licenceAnalysisDto.setEndDate(endDateTimestamp);
        licenceAnalysisDto.setPermissionDtoList(licenceFilePermissionDtoList);
        licenceAnalysisDto.setLocalLicence(licenceFileDto.isLocalLicence());

        licenceService.analysis(licence, licenceAnalysisDto);

        // 判断授权时间
        DateTime now = DateUtil.date();
        DateTime startDate = DateTime.of(startDateTimestamp);

        if (now.isBefore(startDate)) {
            return ResultBean.fail(LicenceStateEnum.FUTURE.getValue(), "当前Licence授权时间从" + startDate.toDateStr() + "开始，请届时登录或重新申请Licence!");
        }

        return ResultBean.success("Licence解析成功");
    }

    /**
     * licence过期提醒
     *
     * @return
     */
    @GetMapping("/remind")
    public ResultBean remind() {
        return ResultBean.success(licenceService.listRemindModule());
    }

    /**
     * licence过期校验
     *
     * @return
     */
    @PostMapping("/tools/expired")
    public ResultBean expired() {
        licenceService.expired();
        return ResultBean.success("");
    }

//    /**
//     * 获取基础配置模块数据md5消息摘要
//     *
//     * @return
//     */
//    @GetMapping("/tools/module/md5")
//    public ResultBean moduleMD5() {
//        String validMD5 = baseModuleMenuMappingService.getValidMD5();
//        return ResultBean.success(validMD5);
//    }
//
//    /**
//     * 根据json生成licence
//     *
//     * @return
//     */
//    @PostMapping("/tools/gen")
//    public ResultBean gen(@RequestBody JSONObject jsonObject) {
//        return ResultBean.success(AESUtil.encrypt(jsonObject.toJSONString(), BaseConfigCodes.LICENCE_AES_KEY));
//    }
//
//    /**
//     * 更新授权模块开始时间和结束时间
//     *
//     * @return
//     */
//    @PostMapping("/tools/updateAuth")
//    public ResultBean updateAuth(@RequestBody LicenceModuleAuth licenceModuleAuth) {
//        LambdaQueryWrapper<LicenceModuleAuth> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(LicenceModuleAuth::getModuleName, licenceModuleAuth.getModuleName());
//        queryWrapper.eq(BaseEnterpriseEntity::getOrgCode, licenceModuleAuth.getOrgCode());
//        queryWrapper.eq(BaseEnterpriseEntity::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
//        LicenceModuleAuth moduleAuthServiceOne = licenceModuleAuthService.getOne(queryWrapper);
//        if (moduleAuthServiceOne == null) {
//            return ResultBean.fail(981,"授权模块不存在");
//        }
//
//        moduleAuthServiceOne.setStartTime(AESUtil.encrypt(String.valueOf(DateUtil.parse(licenceModuleAuth.getStartTime()).getTime()),
//                StrUtil.sub(StrUtil.fillAfter(moduleAuthServiceOne.getModuleCode(), 'w', 16), 0, 16)));
//        moduleAuthServiceOne.setEndTime(AESUtil.encrypt(String.valueOf(DateUtil.parse(licenceModuleAuth.getEndTime()).getTime()),
//                StrUtil.sub(StrUtil.fillAfter(moduleAuthServiceOne.getModuleCode(), 'w', 16), 0, 16)));
//        licenceModuleAuthService.updateById(moduleAuthServiceOne);
//        return expired();
//    }

}

